#pragma once
#include "stream/streambuf.hpp"
#include <ostream>

namespace JHCPP
{
	namespace stream
	{
		class CBase64EncodeBuf : public UnbufferedStreamBuf
		{
		public:
			CBase64EncodeBuf(std::ostream& ostr);
			~CBase64EncodeBuf();

			int close();
			void setLineLength(int lineLength);
			int getLineLength() const;

		private:
			int writeToDevice(char c);

			unsigned char   m_group[3];
			int             m_groupLength;
			int             m_pos;
			int             m_lineLength;
			std::streambuf& m_buf;

			static const unsigned char OUT_ENCODING[64];

			friend class CBase64DecodeBuf;

			CBase64EncodeBuf(const CBase64EncodeBuf&);
			CBase64EncodeBuf& operator = (const CBase64EncodeBuf&);
		};


		class CBase64EncodeIOS : public virtual std::ios
		{
		public:
			CBase64EncodeIOS(std::ostream& ostr);
			~CBase64EncodeIOS();
			int close();
			CBase64EncodeBuf* rdbuf();

		protected:
			CBase64EncodeBuf m_buf;

		private:
			CBase64EncodeIOS(const CBase64EncodeIOS&);
			CBase64EncodeIOS& operator = (const CBase64EncodeIOS&);
		};

		class CBase64Encode : public CBase64EncodeIOS, public std::ostream
		{
		public:
			CBase64Encode(std::ostream& ostr);
			~CBase64Encode();

		private:
			CBase64Encode(const CBase64Encode&);
			CBase64Encode& operator = (const CBase64Encode&);
		};
	}//end of namespace stream
}//end of namespace JHCPP
